\appendix

\singlespacing

\section{Derivations}

\subsection{Least Squares Derivation \label{app:leastSquaresDerivation}}

\begin{align*}
  S &= \sum_{i=1}^n (a t_i^2+ u t_i + c - x_i)^2 \\
  {} &= \sum_{i=1}^n (a^2 t_i^4 + u^2 t_i^2 + c^2 + x_i^2 + 2au t_i^3 +
  2ac t_i^2 + 2uc t_i - 2a t_i^2x_i - 2u t_i x_i - 2c x_i) \\
  {} &= (a^2 \sum_{i=1}^n t_i^4 + u^2 \sum_{i=1}^n t_i^2 + n c^2 + \sum_{i=1}^n
  x_i^2 + 2au \sum_{i=1}^n t_i^3 + 2ac \sum_{i=1}^n t_i^2 + 2uc \sum_{i=1}^n t_i
  - 2a \sum_{i=1}^n t_i^2x_i - 2u \sum_{i=1}^n t_i x_i - 2c \sum_{i=1}^n x_i) \\
  {} &= (a^2 \sum_{i=1}^n t_i^4 + 2au \sum_{i=1}^n t_i^3 + (u^2 + 2ac)
  \sum_{i=1}^n t_i^2 + 2uc \sum_{i=1}^n t_i + \sum_{i=1}^n
  x_i^2 - 2a \sum_{i=1}^n t_i^2x_i - 2u \sum_{i=1}^n t_i x_i - 2c \sum_{i=1}^n
  x_i + nc^2) \\
  \frac{\partial S}{\partial a} &= 2a \sum_{i=1}^n t_i^4+2u \sum_{i=1}^n t_i^3 +
  2c \sum_{i=1}^n t_i^2 - 2 \sum_{i=1}^n t_i^2x_i \\
  \frac{\partial S}{\partial u} &= 2a \sum_{i=1}^n t_i^3 + 2u \sum_{i=1}^n t_i^2
  + 2c \sum_{i=1}^n t_i - 2 \sum_{i=1}^n t_i x_i \\
  \frac{\partial S}{\partial c} &= 2a \sum_{i=1}^n t_i^2 + 2u \sum_{i=1}^n t_i +
  2nc - 2 \sum_{i=1}^n x_i
\end{align*}

Assuming all three equations are at a minimum:

\begin{align*}
  \frac{\partial S}{\partial a} &= 0 \\
  \frac{\partial S}{\partial u} &= 0 \\
  \frac{\partial S}{\partial c} &= 0
\end{align*}

Therefore:

\begin{equation*}
  \left[
   \begin{matrix}
    \sum t_i^4 & \sum t_i^3 & \sum t_i^2 \\
    \sum t_i^3 & \sum t_i^2 & \sum t_i^1 \\
    \sum t_i^2 & \sum t_i^1 & \sum n
   \end{matrix}
  \right]
  \left[
   \begin{matrix}
    a \\
    u \\
    c
   \end{matrix}
  \right]
  =
  \left[
   \begin{matrix}
    \sum t_i^2 y_i \\
    \sum t_i y_i \\
    \sum y_i
   \end{matrix}
  \right]
\end{equation*}

\section{OpenCL Kernels\label{sub:OpenCL-Kernels}}

The following listings contain a sub-set of the total code produced. The full
code listings can be found on the included CD, along with the required build
instructions and any additional libraries.

\subsection{Basic Field Shapes}

\lstset{language=C, morekeywords={float2, inline, __constant, __global, int2,
size_t, __kernel},basicstyle=\small\ttfamily}

\subsubsection{Gaussian Repulsive Field\label{app:gaussianRepulsive}}

\begin{lstlisting}
inline float basicRepel(float2 realPos, float2 repulser)
{
  float2 diff = repulser - realPos;
  return OBSTACLE_WEIGHT * native_exp(-((diff.x*diff.x) + (diff.y*diff.y)) /
  (2*OBSTACLE_SIGMA)); 
}
\end{lstlisting}

\subsubsection{Stretched Gaussian Repulsive
Field\label{app:stretchedGaussianRepulsive}}

\begin{lstlisting}
inline float stretchedBasicRepel(float2 realPos, float2 repulser)
{
  float2 diff = repulser - realPos;
  return OBSTACLE_WEIGHT * native_exp(-((diff.x*diff.x) / (2* OBSTACLE_SIGMA *
  6) + (diff.y*diff.y)/ (2*OBSTACLE_SIGMA)) ); 
}
\end{lstlisting}

\subsection{Field Calculations}

\subsubsection{Initial Approach Field\label{app:initialApproachField}}

\begin{lstlisting}
// Calculates the field at a given point
float fieldAtPoint(float2 realPos, float2 ball, float2 ballVelocity, 
                   __constant float2 *basicRepulsers)
{
  float2 posShift = normalize(ballVelocity) * -7;
  float2 attractBall = ball - posShift;
  float2 repelBall = ball + posShift;
  float dist = distance(attractBall, realPos);
  float attractField = BALL_WEIGHT * dist;

  float repField;

  if (length(posShift) > 1.0f)
    repField += basicRepel(realPos, repelBall);

  for (int i = 0; i < 10; i++)
  {
    repField += basicRepel(realPos, basicRepulsers[i]);
  }

  return attractField + repField;
}

// Used to calculate the entire field
__kernel void main(float2 ball, float fieldResolution, 
                   __constant float2 *basicRepulsers, __global float * out,
                   float2 ballVelocity) 
{
  int2 gridPos = (int2)(get_global_id(0), get_global_id(1));

  size_t index = gridPos.x + gridPos.y * get_global_size(0);

  float2 realPos = convert_float2(gridPos) * fieldResolution;

  float res = fieldAtPoint(realPos, ball, ballVelocity, basicRepulsers);

  out[index] = res;
}

// Used to calculate the field at a set of given points
__kernel void fieldAtPoints(float2 ball, __constant float2 *fieldPoints, 
                            __constant float2 *basicRepulsers, 
                            __global float *out, float2 ballVelocity) 
{
  size_t pointId = get_global_id(0);

  out[pointId] = fieldAtPoint(fieldPoints[pointId], ball, ballVelocity,
  basicRepulsers); 
}
\end{lstlisting}

\subsubsection{Ball Possession Field \label{app:possessionField}}

\begin{lstlisting}
// Calculates the possession field at a given point
float possessionFieldAtPoint(float2 realPos, float2 ball, 
                             __constant float2 *basicRepulsers, 
                             float2 goalTarget) 
{
  float2 vectorToGoal = normalize(goalTarget - realPos) * 5;
  float2 attractBall = ball + vectorToGoal;

  float dist = distance(attractBall, realPos);
  float attractField = BALL_WEIGHT * dist;

  float repField = 0;

  for (int i = 0; i < 10; i++)
  {
    repField += basicRepel(realPos, basicRepulsers[i]);
  }

  return attractField + repField;
}

// Used to calculate the entire possession field
__kernel void possessionMain(float2 ball, float2 goalTarget, 
                             float fieldResolution, 
                             __constant float2 *basicRepulsers, 
                             __global float *out) 
 { 
  int2 gridPos = (int2)(get_global_id(0), get_global_id(1));

  size_t index = gridPos.x + gridPos.y * get_global_size(0);

  float2 realPos = convert_float2(gridPos) * fieldResolution;

  float res = possessionFieldAtPoint(realPos, ball, basicRepulsers, goalTarget);

  out[index] = res;
}

// Used to calculate the possession field at a given point
__kernel void possessionFieldAtPoints(float2 ball, float2 goalTarget, 
                                      __constant float2 *fieldPoints, 
                                      __constant float2 *basicRepulsers, 
                                      __global float *out) 
{
  size_t pointId = get_global_id(0);

  out[pointId] = possessionFieldAtPoint(fieldPoints[pointId], ball,
  basicRepulsers, goalTarget); 
}
\end{lstlisting}

\section{Code Listings}

The following listings contain a sub-set of the total code produced.  The full
code listings can be found on the included CD, along with the required build
instructions and any additional libraries.

\lstset{language=C++}

\subsection{Velocity Controller\label{app:velControl}}

\begin{lstlisting}
void VelocityController::Control(Vector3D targetVelocity, 
                                 Vector3D currentVelocity, Robot* bot, 
                                 bool absoluteVelocity, bool nearBall)
{
  // Get the difference between the current and desired velocity
  auto diff = Utilities::Subtract(targetVelocity, currentVelocity); 
  auto angle = atan2(diff.y, diff.x);  // Work out the angle difference
  // Get the robot's angle in radians
  auto botAngle = DEGREES_TO_RADIANS(bot->rotation);
  // Get the magnitude of the velocity error 
  auto error = Utilities::Length(diff); 

  // If the velocity is supposed to be an absolute velocity, translate it into a
  // relative one
  if (absoluteVelocity) 
    angle = angle - botAngle;

  // Normalise between pi and -pi
  if (angle > M_PI)
    angle -= 2 * M_PI;
  if (angle < -M_PI)
    angle += 2 * M_PI;

  if (fabs(angle) > M_PI/2) 
  {
    // Target is behind is, will be quicker to go backwards
    // Rotate target angle around 180 degrees
    error = -error;
    angle += M_PI;
    // Normalise between pi and -pi
    if (angle > M_PI)
      angle -= 2 * M_PI;
    if (angle < -M_PI)
      angle += 2 * M_PI;
  }

  auto turnSpeed = angle * angleProportionalTerm;
  bot->velocityLeft = -turnSpeed;
  bot->velocityRight = turnSpeed;

  // If we're nearly at the right angle, or near the ball, try to turn and move
  if (fabs(angle) < DEGREES_TO_RADIANS(20) || nearBall) 
  {
    // Work out the forwards speed
    auto vel = error * velocityProportionalTerm;
    // Ensure we won't muck up the turn by trying to move too fast forwards
    if (vel + abs(turnSpeed) > MAX_WHEEL_SPEED)
      vel = MAX_WHEEL_SPEED - abs(bot->velocityLeft);

    // Apply the speed.
    bot->velocityLeft += vel;
    bot->velocityRight += vel;
  }
}
\end{lstlisting}

\subsection{Motion Controller\label{app:motionControl}}

\begin{lstlisting}
void MotionController::Control(Vector3D targetPosition, 
                               Vector3D currentVelocity, Robot* bot)
{
  // Get the vector from the robot to the target position
  auto diff = Utilities::Subtract(targetPosition, bot->pos); 
  // Work out the angle to the target position
  auto angle = atan2(diff.y, diff.x);                        
  // Convert the robot angle into radians, which all the C math functions use...
  auto botAngle = DEGREES_TO_RADIANS(bot->rotation);         
  // Get the actual distance to the target position
  auto distance = Utilities::Length(diff);                   
  // Calculate the desired speed
  auto vel = distance * positionProportionalTerm;            

  // Move target angle into robot frame of reference
  angle = angle - botAngle;                                  

  // Normalise the new angle between pi and -pi
  if (angle > M_PI)
    angle -= 2*M_PI;
  if (angle < -M_PI)
    angle += 2*M_PI;

  // Calculate the desired speed
  Vector3D desiredVelocity;                                  
  desiredVelocity.x = vel * cos(angle);                 
  desiredVelocity.y = vel * sin(angle);

  // Pass the information on to the velocity controller
  VelocityController control;                                
  control.Control(desiredVelocity, currentVelocity, bot);    
}
\end{lstlisting}

\subsection{Physics Strategy File\label{app:physicsStrategy}}

\begin{lstlisting}
// Initialises the strategy
extern "C" STRATEGY_API void Create(Environment* env)
{
  auto userData = new UserData();
  env->userData = userData;

  auto t = time(nullptr);
  auto currentTime = localtime(&t);
  userData->outStream << asctime(currentTime) << "," << VELOCITY_INPUT 
                      << std::endl;
}

// Runs the robots on every simulator time-step
extern "C" STRATEGY_API void Strategy(Environment* env)
{
  auto userData = (UserData*) env->userData;
  auto bot = &env->home[1];

  bot->velocityLeft = VELOCITY_INPUT;
  bot->velocityRight = VELOCITY_INPUT;

  LARGE_INTEGER hiResTimer;
  LARGE_INTEGER hiResTimerFreq;
  QueryPerformanceCounter(&hiResTimer);
  QueryPerformanceFrequency(&hiResTimerFreq);

  userData->outStream << hiResTimerFreq.HighPart << "," 
                      << hiResTimerFreq.LowPart << "," << hiResTimer.HighPart 
                      << "," << hiResTimer.LowPart << "," << bot->pos.x << "," 
                      << bot->pos.y << std::endl; 
}
\end{lstlisting}

\cleardoublepage{}

\bibliographystyle{plain}
\bibliography{References/references}